package fogcore

import (
	"fmt"
	"runtime"
	"strconv"
)

//Mask 迷雾，0表示该区域有迷雾，0xff表示没有
type Mask uint8

const (
	HIDE_MASK Mask = 0    //迷雾笼罩
	BARE_MASK Mask = 0xff //迷雾被驱散
)

//Board 迷雾围棋棋盘
type Board struct {
	points []PointStatus //棋盘上共有19*19个落子点
	n      int           //n*n棋盘
	masks  [][]Mask      //迷雾 masks[player]获取对应的 []Mask
}

func (b Board) GetPoint(v Vec2) PointStatus {
	if b.rangeCheck(v) {
		_, file, line, _ := runtime.Caller(0)
		panic(file + ":" + strconv.Itoa(line) + " 越界了")
	}
	return b.points[v.X*b.n+v.Y]
}

func (b Board) SetPoint(v Vec2, p PointStatus) {
	if b.rangeCheck(v) {
		_, file, line, _ := runtime.Caller(0)
		panic(file + ":" + strconv.Itoa(line) + " 越界了")
	}
	b.points[v.X*b.n+v.Y] = p
}

func (b Board) GetMask(i PointStatus, v Vec2) Mask {
	if b.rangeCheck(v) {
		_, file, line, _ := runtime.Caller(0)
		panic(file + ":" + strconv.Itoa(line) + " 越界了")
	}
	return b.masks[i][v.X*b.n+v.Y]
}

func (b Board) SetMask(i PointStatus, v Vec2, m Mask) {
	if b.rangeCheck(v) {
		_, file, line, _ := runtime.Caller(0)
		panic(file + ":" + strconv.Itoa(line) + " 越界了")
	}
	b.masks[i][v.X*b.n+v.Y] = m
}

//HasStones 该点有子
func (b Board) HasStones(v Vec2) bool {
	return b.GetPoint(v).HasStones()
}

//rangeCheck 是否越界
func (b Board) rangeCheck(v Vec2) bool {
	return RangeCheck(b.n, v)
}

var moves = [4]Vec2{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}

//有气，落子周围没有其他棋子
func (b Board) hasLiberty(v Vec2) bool {
	for _, m := range moves {
		if !b.rangeCheck(m.Add(v)) && !b.HasStones(m.Add(v)) {
			return true
		}
	}
	return false
}

//该点上是空的，没有棋子
func (b Board) isEmpty(v Vec2) bool {
	return b.GetPoint(v) == C_EMPTY
}

func GetArrPoint(arr []PointStatus, n int, v Vec2) PointStatus {
	if RangeCheck(n, v) {
		_, file, line, _ := runtime.Caller(0)
		panic(file + ":" + strconv.Itoa(line) + " 越界了")
	}
	return arr[v.X*n+v.Y]
}

func SetArrPoint(arr []PointStatus, n int, v Vec2, value PointStatus) {
	if RangeCheck(n, v) {
		_, file, line, _ := runtime.Caller(0)
		panic(file + ":" + strconv.Itoa(line) + " 越界了")
	}
	arr[v.X*n+v.Y] = value
}

func (b Board) Print(color PointStatus) string {
	rs := ""
	for i := 0; i < b.n; i++ {
		rs += fmt.Sprintf("%v\t%v\n", b.points[i*b.n:(i+1)*b.n], b.masks[color][i*b.n:(i+1)*b.n])
	}
	return rs
}

//RangeCheck 越界检查
func RangeCheck(n int, v Vec2) bool {
	return v.X < 0 || v.Y < 0 || v.X >= n || v.Y >= n
}
